import { speechRecognizer } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { bundleManager, common } from '@kit.AbilityKit';
import { WorkerPort } from '../common/WorkerPort';
import tts from './ttsCtrl';

const permissions: Array<Permissions> = ['ohos.permission.MICROPHONE'];

export async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;

  // 获取应用程序的accessTokenID
  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo =
      await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
  }

  // 校验应用是否被授予权限
  try {
    grantStatus = await atManager.checkAccessToken(tokenId, permission);
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
  }

  return grantStatus;
}

export class asrCtrl {
  private asrEngine: speechRecognizer.SpeechRecognitionEngine = null!
  extraParams: Record<string, Object> = { "locate": "CN", "recognizerMode": "short" }
  private _id = 0;
  private _workPort: WorkerPort;
  private _context: common.UIAbilityContext;

  // private requestPermission;


  // constructor(port: PortProxy) {
  //   this._workPort = port;
  //   console.log("cocos info initted asr")
  //   this._workPort.on('startSpeech', () => {
  //     this.startSpeech();
  //   });
  //   this._workPort.on('endSpeech', () => {
  //     this.onEnd();
  //   });
  //   this.init();
  // }

  init(port: WorkerPort) {
    if (this.asrEngine) {
      return;
    }
    this._workPort = port;
    let initParamsInfo: speechRecognizer.CreateEngineParams = {
      language: 'zh-CN',
      online: 1,
      extraParams: this.extraParams
    };

    // 创建引擎实例相关参数
    speechRecognizer.createEngine(initParamsInfo, (err: BusinessError, speechRecognitionEngine:
      speechRecognizer.SpeechRecognitionEngine) => {
      if (!err) {
        // 接收创建的引擎实例
        this.asrEngine = speechRecognitionEngine;
        let setListener: speechRecognizer.RecognitionListener = {
          // 开始识别成功回调
          onStart(sessionId: string, eventMessage: string) {
            // console.info("asr onStart sessionId: " + sessionId + "eventMessage: " + eventMessage);
          },
          // 事件回调
          onEvent(sessionId: string, eventCode: number, eventMessage: string) {
            // console.info("asr onEvent sessionId: " + sessionId + "eventCode: " + eventCode + "eventMessage: " + eventMessage);
          },
          // 识别结果回调，包括中间结果和最终结果
          onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) {
            if (result.isFinal) {
              port.postMessage('endASR', result.result);
            } else {
              port.postMessage('onASR', result.result);
            }

          },
          // 识别完成回调
          onComplete(sessionId: string, eventMessage: string) {
            console.info("asr onComplete sessionId: " + sessionId + "eventMessage: " + eventMessage);
          },
          // 错误回调，错误码通过本方法返回
          // 返回错误码1002200002，开始识别失败，重复启动startListening方法时触发
          // 更多错误码请参考错误码参考
          onError(sessionId: string, errorCode: number, errorMessage: string) {
            // console.error("asr onError sessionId: " + sessionId + "errorCode: " + errorCode + "errorMessage: " + errorMessage);
          },
        }
        // 设置回调
        this.asrEngine.setListener(setListener);

      } else {
        // 无法创建引擎时返回错误码1002200001，原因：语种不支持、模式不支持、初始化超时、资源不存在等导致创建引擎失败
        // 无法创建引擎时返回错误码1002200006，原因：引擎正在忙碌中，一般多个应用同时调用语音识别引擎时触发
        // 无法创建引擎时返回错误码1002200008，原因：引擎正在销毁中
        console.error("errCode: " + err.code + " errMessage: " + err.message);
      }
    });

  }

  setContext(context: common.UIAbilityContext) {
    this._context = context;
  }

  reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
    atManager.requestPermissionsFromUser(context, permissions).then((data) => {
      let grantStatus: Array<number> = data.authResults;
      let length: number = grantStatus.length;
      for (let i = 0; i < length; i++) {
        if (grantStatus[i] === 0) {
          // 用户授权，可以继续访问目标操
        } else {
          // 用户拒绝授权，提示用户必须授权才能访问当前页面的功能，并引导用户到系统设置中打开相应的权限
          return;
        }
      }
      // 授权成功
    }).catch((err: BusinessError) => {
      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

  private _started = false

  async startSpeech() {

    console.log("cocos info start asr")

    let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]);

    if (grantStatus !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      console.info("speech" + grantStatus)
      // const res = requestPermission(this._context,permissions)
      this.reqPermissionsFromUser(permissions, this._context);
      return;
    }
    this.onStart();


  }

  onStart() {
    this._started = true;
    tts.stop();
    this._id++;
    // 设置开始识别相关参数
    let recognizerParams: speechRecognizer.StartParams = {
      sessionId: this._id + "",
      audioInfo: {
        audioType: 'pcm',
        sampleRate: 16000,
        soundChannel: 1,
        sampleBit: 16
      },
      extraParams: { "recognitionMode": 0 }
    }
    // 调用开始识别方法
    this.asrEngine.startListening(recognizerParams);
  }

  onEnd() {
    if (!this._started) {
      return;
    }

    this.asrEngine.finish(this._id + "");
    this._started = false;

  }
}

let asr = new asrCtrl();

export default asr as asrCtrl;